package cn.codesugar.videocache

import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.SeekBar
import androidx.fragment.app.Fragment
import cn.codesugar.videocache.databinding.FragmentVideoBinding
import com.danikula.videocache.CacheListener
import com.danikula.videocache.ProxyCacheManager
import java.io.File

/**
 * An example full-screen fragment that shows and hides the system UI (i.e.
 * status bar and navigation/system bar) with user interaction.
 */
class VideoFragment(private var url: String) : Fragment(), CacheListener {

    private var _binding: FragmentVideoBinding? = null
    private val binding get() = _binding!!

    private val updater: VideoProgressUpdater = VideoProgressUpdater()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentVideoBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        checkCachedState()
        startVideo()
        binding.progressBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {

            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {}

            override fun onStartTrackingTouch(seekBar: SeekBar?) {}

            override fun onStopTrackingTouch(seekBar: SeekBar?) {
                binding.videoView.apply {
                    val videoPosition: Int = duration * binding.progressBar.progress / 100
                    seekTo(videoPosition)
                }
            }

        })
    }

    override fun onResume() {
        super.onResume()
        updater.start()
    }

    override fun onPause() {
        super.onPause()
        updater.stop()
    }

    override fun onDestroy() {
        super.onDestroy()
        binding.videoView.stopPlayback()
        ProxyCacheManager.getProxy(requireContext()).unregisterCacheListener(this)
        _binding = null
    }

    override fun onCacheAvailable(cacheFile: File?, url: String?, percentsAvailable: Int) {
        binding.progressBar.secondaryProgress = percentsAvailable
        setCachedState(percentsAvailable == 100)
        Log.d(TAG,
            String.format(
                "缓存可用. 可用比率: %d, 文件: %s, 链接: %s",
                percentsAvailable,
                cacheFile,
                url
            )
        )
    }

    private fun startVideo() {
        val proxy = ProxyCacheManager.getProxy(requireContext())
        proxy.registerCacheListener(this, url)
        val proxyUrl = proxy.getProxyUrl(url)
        Log.d(TAG, "使用代理网址 $proxyUrl 代替原始网址 $url")
        binding.videoView.setVideoPath(proxyUrl)
        binding.videoView.start()
    }

    private fun checkCachedState() {
        val proxy = ProxyCacheManager.getProxy(requireContext())
        val fullyCached = proxy.isCached(url)
        setCachedState(fullyCached)
        if (fullyCached) {
            binding.progressBar.secondaryProgress = 100
        }
    }

    private fun setCachedState(cached: Boolean) {
        val statusIconId = if (cached) R.drawable.ic_cloud_done else R.drawable.ic_cloud_download
        binding.cacheStatusImageView.setImageResource(statusIconId)
    }

    private fun updateVideoProgress() {
        val videoProgress = binding.videoView.currentPosition * 100 / binding.videoView.duration
        binding.progressBar.progress = videoProgress
    }

    private inner class VideoProgressUpdater : Handler(Looper.getMainLooper()) {
        fun start() {
            sendEmptyMessage(0)
        }

        fun stop() {
            removeMessages(0)
        }

        override fun handleMessage(msg: Message) {
            updateVideoProgress()
            sendEmptyMessageDelayed(0, 500)
        }
    }
}